package org.exia.minisig.swing.view.common;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.exia.minisig.model.object.DescriptibleElement;
import org.exia.minisig.swing.view.home.HomeFram;

@SuppressWarnings("serial")
public class SearchPanel extends JPanel {
	//VAR
	private MiniSIGSwing parent;
	private JTextField fieldSearch;
	private JComboBox<String> combo;
	private ArrayList<DescriptibleElement> listeElement;
	private ArrayList<DescriptibleElement> listeElementTempo;
	//GET & SET
	public JTextField getFieldSearch() {
		return fieldSearch;
	}
	public void setFieldSearch(JTextField fieldSearch) {
		this.fieldSearch = fieldSearch;
	}
	//CONSTRUCTOR
	public SearchPanel(ArrayList<DescriptibleElement> _listeElement, MiniSIGSwing _parent){
		initializeVar(_listeElement, _parent);
	}
	
	public void initializeVar(final ArrayList<DescriptibleElement> _listeElement,  MiniSIGSwing _parent){
		this.setBackground(Color.white);
		this.parent = _parent;
		this.listeElement = _listeElement;
		//-----------------------------------------------------------//
		this.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
		//-----------------------------------------------------------//
		this.setLayout(new GridBagLayout());
		GridBagConstraints gc = new GridBagConstraints();
		gc.fill=GridBagConstraints.BOTH;
		//PARAMETER
		gc.weightx=4;
		gc.weighty=1;
		//panelLabel
		gc.gridx=0;
		gc.gridy=0;
		JPanel test = new JPanel(new BorderLayout(0,0));
		JLabel labelTextsearch = new JLabel("Recherche");
		labelTextsearch.setBackground(Color.white);
		labelTextsearch.setOpaque(true);
		
		labelTextsearch.setVerticalAlignment(SwingConstants.CENTER);
		labelTextsearch.setHorizontalAlignment(SwingConstants.CENTER);
		test.add(labelTextsearch, BorderLayout.CENTER);
		this.add(test, gc);

		//panelField
		gc.insets = new Insets(0, 5, 0, 5);
		gc.weighty=2;
		gc.gridx=0;
		gc.gridy=1;
		this.fieldSearch = new JTextField();
		//FIELD PARAM 1)
		this.fieldSearch.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
		this.fieldSearch.setMargin(new Insets(50, 0, 0, 0));
		this.fieldSearch.setBorder(BorderFactory.createCompoundBorder(
				this.fieldSearch.getBorder(), 
		        BorderFactory.createEmptyBorder(0, 10, 0, 10)));
		//FIELD PARAM 2
		this.fieldSearch.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void changedUpdate(DocumentEvent e) {
			}
			@Override
			public void insertUpdate(DocumentEvent e) {
				sortDocument();
			}
			@Override
			public void removeUpdate(DocumentEvent e) {
				sortDocument();
			}
			public void sortDocument(){
				if (!fieldSearch.getText().equals("")){
					switch ((String)combo.getSelectedItem()) {
					case "Nom exact":
						fullMatch();
						break;
					case "Relation":
						ElementMatch();
						break;
					case "Contenu":
						wordMatch();
					default:
						break;
					}
				} else {
					mergeList();
				}
				parent.reload();
				fieldSearch.requestFocus();
			}
		});
		
		this.add(this.fieldSearch, gc);
		//panelCombo
		gc.insets = new Insets(0, 5, 20, 5);
		gc.gridx=0;
		gc.gridy=2;
		this.combo = new JComboBox<>();
		this.combo.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
		this.combo.addItem("Nom exact");
		this.combo.addItem("Contenu");
		this.combo.addItem("Relation");
		this.add(this.combo, gc);
	}
	//METHODE
	private void mergeList(){
		listeElement.addAll(listeElementTempo);
		listeElementTempo = new ArrayList<>();
	}
	
	private void fullMatch(){
		if (listeElementTempo == null){
			listeElementTempo = new ArrayList<>();
		} else {
			for (DescriptibleElement element : listeElementTempo) {
				listeElement.add(element);
			}
			listeElementTempo = new ArrayList<>();
		}
		while (!haveOnly(listeElement, fieldSearch.getText())) {
			for (int i = 0; i < listeElement.size() ; i++) {
				if (!listeElement.get(i).getLabel().equals(fieldSearch.getText())){
					listeElementTempo.add(listeElement.get(i));
					listeElement.remove(i);
				}			
			}
		}
		this.revalidate();
	}
	public boolean haveOnly(ArrayList<DescriptibleElement> liste, String toHave){
		for (DescriptibleElement item : liste) {
			if (!item.getLabel().equals(toHave)){
				return false;
			}
		}
		return true;
	}
	
	private void wordMatch(){
		if (listeElementTempo == null){
			listeElementTempo = new ArrayList<>();
		} else {
			for (DescriptibleElement element : listeElementTempo) {
				listeElement.add(element);
			}
			listeElementTempo = new ArrayList<>();
		}
		if (elementHasNotWord(listeElement, fieldSearch.getText())){
			while (elementHasNotWord(listeElement, fieldSearch.getText())) {
				for (int i = 0; i < listeElement.size()  ; i++) {
					if (!haveWord(listeElement.get(i), fieldSearch.getText())){
						listeElementTempo.add(listeElement.get(i));
	                    listeElement.remove(i);
	                    break;
					} 
               }
			}
		}
	}
	
	public boolean elementHasNotWord(ArrayList<DescriptibleElement> liste, String toHave){
		boolean allHave = true;
		
		for (DescriptibleElement element: liste) {
			if (!allHave){
				break;
			}
			boolean elementHave = false;
			for (String word : element.getText().split(" ")) {
				if (word.equals(toHave)){
					elementHave = true;
				}
			}
			if (!elementHave){
				allHave = false;
			}
		}
		return !allHave;
	}
	public boolean haveWord(DescriptibleElement element, String toHave){
		for (String word : element.getText().split(" ")) {
			if (word.equals(toHave)){
				return true;
			}
		}
		return false;
		
	}
	
	private void ElementMatch(){
		//TODO 
		//IMPLEMENTER APRES EVOLUTION DE NEWS 
	}

}